package com.hcj.springcloud.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * CaffeineCache个性化配置
 */
@Slf4j
@Configuration
public class CaffeineCacheConfig {
    @Bean
    CacheManager cacheManager() {
        SimpleCacheManager manager = new SimpleCacheManager();
        ArrayList<CaffeineCache> caches = new ArrayList<>();
        for (Caches c : Caches.values()) {
            caches.add(new CaffeineCache(c.name(),
                    Caffeine.newBuilder()
                            .recordStats()
                            .expireAfterAccess(c.expireTimeSecond, TimeUnit.SECONDS)
                            .maximumSize(c.getMaxSize())
                            .removalListener((key, value, cause) -> {
                                log.info("key:{} \t value:{} \t delete cause:{}", key, value, cause);
                            })
                            .build())
            );
        }
        manager.setCaches(caches);
        return manager;
    }

    /**
     * 枚举类
     */
    enum Caches {
        CACHE_NAME_2_HOUR(7200L, 1000),
        CACHE_NAME_10_SECOND(10L, 1000);

        private Long expireTimeSecond;
        private Integer maxSize;

        Caches() {

        }

        Caches(Long expireTimeSecond, Integer maxSize) {
            this.expireTimeSecond = expireTimeSecond;
            this.maxSize = maxSize;
        }

        public Long getExpireTimeSecond() {
            return expireTimeSecond;
        }

        public void setExpireTimeSecond(Long expireTimeSecond) {
            this.expireTimeSecond = expireTimeSecond;
        }

        public Integer getMaxSize() {
            return maxSize;
        }

        public void setMaxSize(Integer maxSize) {
            this.maxSize = maxSize;
        }
    }
}
